/*----------------------------------------------------------------------
 * This file implements the Foo component that exposes the nsIHelloWorld
 * interface. The implementation consists of 2 parts: the component
 * module (acting like an instance factory) and a function that creates
 * instances actually implementing the nsIHelloWorld interface.
 *----------------------------------------------------------------------
 */
 
/*
 *  ATTENTION
 *
 *  Firefox is very very unforgiving to syntax errors in XPCOM Javascript
 *  files. If this file does not parse properly once, it might not be
 *  loaded again even if you restart Firefox. Watch the JavaScript
 *  Console for any error message (only logged the first time the file
 *  fails to parse).
 *
 *  You might have to uninstall the whole extension, restart Firefox, 
 *  reinstall the extension (with fixes), and then restart Firefox.
 */
function _trace(msg) {
    Components.classes["@mozilla.org/consoleservice;1"]
    .getService(Components.interfaces.nsIConsoleService)
    .logStringMessage(msg);
}
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const ctor = Components.Constructor;
const Exception = Components.Exception;
const module = Components.utils.import;
const error = Components.utils.reportError;

module("resource://gre/modules/XPCOMUtils.jsm");

const NS_ERROR_NO_INTERFACE = Cr.NS_ERROR_NO_INTERFACE;
const NS_ERROR_FAILURE = Cr.NS_ERROR_FAILURE;
const NS_ERROR_NO_AGGREGATION = Cr.NS_ERROR_NO_AGGREGATION;
const NS_ERROR_INVALID_ARG = Cr.NS_ERROR_INVALID_ARG;

 
function _printToJSConsole(msg) {
    Components.classes["@mozilla.org/consoleservice;1"]
    .getService(Components.interfaces.nsIConsoleService)
    .logStringMessage(msg);
}





/*----------------------------------------------------------------------
 * The Foo Component, implemented as a Javascript function.
 *----------------------------------------------------------------------
 */

function FooComponent() {
    /*
     *  This is a XPCOM-in-Javascript trick: Clients using an XPCOM
     *  implemented in Javascript can access its wrappedJSObject field
     *  and then from there, access its Javascript methods that are
     *  not declared in any of the IDL interfaces that it implements.
     *
     *  Being able to call directly the methods of a Javascript-based
     *  XPCOM allows clients to pass to it and receive from it
     *  objects of types not supported by IDL.
     */
    this.wrappedJSObject = this;
    
    this._initialized = false;
    this._packages = null;
}

 

/*
 *  Initializes this component, including loading JARs.
 */
FooComponent.prototype ={
    classDescription: "Description of project to help user understand the usage or purpose",
    contractID: "@ff-ext-in-java.googlecode.com/ffjepC1;1",
    classID: Components.ID("{ddb81f4c-87cc-40d3-ba17-48ca1fb74890}"),
    service: true,
    QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports , Ci.nsIHelloWorld,Ci.brzIHelloWorld,Ci.brzISayHello]),
    _xpcom_categories: [{
        category: 'profile-after-change'
    }],
    say : function HW_say(lang) {
        
        
        
        if(lang==Ci.brzISayHello.ENGLISH) {
            return 'Hello World!';
        }
        if(lang==Ci.brzISayHello.HUNGARIAN) {
            return '\u00dcdv Vil\u00e1g!';
        }
        if(lang==Ci.brzISayHello.FRENCH) {
            return 'Bonjour tout le monde';
        }
        if(lang==Ci.brzISayHello.ITALIAN) {
            return 'ciao a tutti';
        }
        return 'Hello ...';    
    }
    
}
if (XPCOMUtils.generateNSGetFactory) {
    var NSGetFactory = XPCOMUtils.generateNSGetFactory([FooComponent]);
}
else {
function NSGetModule() XPCOMUtils.generateModule([FooComponent]);
}

FooComponent.prototype.initialize = function (packageLoader, trace) {
    _trace('initialization started');
    

    if (this._initialized) {
        this._trace("FooComponent.initialize already called before");
        return true;
    }
    //    
    this._traceFlag = (trace);
        
    this._trace("FooComponent.initialize {");
    try {
        this._packageLoader = packageLoader;
            
        var extensionPath = this._getExtensionPath("ffjep");
            
        /*
             *  Enumerate URLs to our JARs and class directories
             */
        //Do we need to know all the jar's name?  for know: YES
        var javaPath = extensionPath + "java/";
        var jarExtensionServicePath=extensionPath +"extensions/service/";
        var jarFilepaths = [
                
        //javaPath + "classes/", // our own classes, compiled from ...
        jarExtensionServicePath+"ffjep-0.0.1-SNAPSHOT.jar"
                
                
        //javaPath + "lib/javax.servlet-5.1.4.jar" // a sample JAR WE don't need this so far
        ];
        this._packages = this._packageLoader(jarFilepaths, this._traceFlag);
            
        /*
             *  Test out a static method
             */
        this._trace("Greetings: " + 
            this._packages.getClass("edu.mit.simile.javaFirefoxExtension.Test").m("getGreetings")()
            );
            
        /*
             *  Create a sample Java object
             */
        this._test = this._packages.getClass("edu.mit.simile.javaFirefoxExtension.Test").n(42);
        this._trace("Environment Variable PATH = " + this._test.getEnvironmentVariable("PATH"));
             
        this._initialized = true;
    } catch (e) {
        this._fail(e);
        this._trace(this.error);
    }
    this._trace("} FooComponent.initialize");
    //    
    return this._initialized;
};


//
FooComponent.prototype._fail = function(e) {
    if (e.getMessage) {
        this.error = e + ": " + e.getMessage() + "\n";
        while (e.getCause() != null) {
            e = e.getCause();
            this.error += "caused by " + e + ": " + e.getMessage() + "\n";
        }
    } else {
        this.error = e;
    }
};
//
FooComponent.prototype._trace = function (msg) {
    if (this._traceFlag) {
        _printToJSConsole(msg);
    }
}



/*
 *  Get the file path to the installation directory of this 
 *  extension.
 */
FooComponent.prototype._getExtensionPath = function(extensionName) {
    _printToJSConsole("dbg FFJEP BrZ - 1:");
    
    var chromeRegistry =
    Components.classes["@mozilla.org/chrome/chrome-registry;1"]
    .getService(Components.interfaces.nsIChromeRegistry);
            
    var uri =
    Components.classes["@mozilla.org/network/standard-url;1"]
    .createInstance(Components.interfaces.nsIURI);
    
    uri.spec = "chrome://" + extensionName + "/content/";
    _printToJSConsole("dbg FFJEP BrZ - 2:");
    var path = chromeRegistry.convertChromeURL(uri);
    if (typeof(path) == "object") {
        path = path.spec;
    }
    
    path = path.substring(0, path.indexOf("/chrome/") + 1);
    
    return path;
};

/*
 *  Returns the packages of all the JARs that this component has loaded.
 */
FooComponent.prototype.getPackages = function() {
    this._trace("FooComponent.getPackages");
    return this._packages;
};

/*
 *  Returns the Test object instantiated by default.
 */
FooComponent.prototype.getTest = function() {
    this._trace("FooComponent.getTest");
    return this._test;
};
//


    
/*
 *  Retrieve the file path to the user's profile directory.
 *  We don't really use it here but it might come in handy
 *  for you.
 */
//FooComponent.prototype._getProfilePath = function() {
//var fileLocator =
//    Components.classes["@mozilla.org/file/directory_service;1"]
//.getService(Components.interfaces.nsIProperties);
//    
//var path = escape(fileLocator.get("ProfD", Components.interfaces.nsIFile).path.replace(/\\/g, "/")) + "/";
//if (path.indexOf("/") == 0) {
//    path = 'file://' + path;
//} else {
//    path = 'file:///' + path;
//}
//    
//return path;
//};



